package data;

import database.DataBaseConnection;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Properties;

public class GetStack {
    private String year;
    private String month;
    private String[] tableName = {"encryption", "decryption", "signature", "verification", "signcryption",
            "unsigncryption", "mac", "authenticated_encryption", "decryption_verification"};

    public GetStack(String year, String month) {
        this.year = year;
        this.month = month;
    }

    public String getData() {
        Properties properties = new Properties();
        InputStreamReader inputStreamReader = null;
        try {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            InputStream inputStream = classLoader.getResourceAsStream("dateFormat.properties");
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            properties.load(inputStreamReader);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStreamReader != null)
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        String sql, result = "";
        Connection connection = DataBaseConnection.getConnection();
        JSONArray jsonArray = new JSONArray();
        if (connection != null) {
            if (month.equals("all")) {//获取月视图
                String format = properties.getProperty("month");
                SimpleDateFormat sdf = new SimpleDateFormat("MM");
                for (String name : this.tableName) {
                    JSONObject jsonObject = new JSONObject();
                    HashMap<String, Integer> hashMap = new HashMap<>();
                    sql = "select DATE_FORMAT(execute_time,'" + format + "') month,count(id) count from " + name
                            + " where year(execute_time) = ? group by month order by month ASC";
                    try {
                        PreparedStatement preparedStatement = connection.prepareStatement(sql);
                        preparedStatement.setString(1, this.year);
                        ResultSet resultSet = preparedStatement.executeQuery();
                        while (resultSet != null && resultSet.next()) {
                            hashMap.put(resultSet.getString("month"),
                                    resultSet.getInt("count"));
                        }
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    //设定初始时间为当年1月
                    Calendar start = this.getYearStarter();
                    for (int i = 0; i < 12; i++) {
                        String str = sdf.format(start.getTime());
                        String key = str + "月";
                        jsonObject.put(key, hashMap.getOrDefault(str, 0));
                        start.add(Calendar.MONTH, 1);
                    }
                    JSONObject object = new JSONObject();
                    object.put(name, jsonObject);
                    jsonArray.add(object);
                }
            } else {//获取日视图
                String format = properties.getProperty("day2");
                SimpleDateFormat sdf = new SimpleDateFormat("dd");
                for (String name : this.tableName) {
                    JSONObject jsonObject = new JSONObject();
                    HashMap<String, Integer> hashMap = new HashMap<>();
                    sql = "select DATE_FORMAT(execute_time,'" + format + "') day,count(id) count from " + name
                            + " where year(execute_time) = ? and month(execute_time) = ? " +
                            "group by day order by day ASC";
                    try {
                        PreparedStatement preparedStatement = connection.prepareStatement(sql);
                        preparedStatement.setString(1, this.year);
                        preparedStatement.setString(2, this.month);
                        ResultSet resultSet = preparedStatement.executeQuery();
                        while (resultSet != null && resultSet.next()) {
                            hashMap.put(resultSet.getString("day"),
                                    resultSet.getInt("count"));
                        }
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    //设定时间为当月1号
                    Calendar start = this.getMonthStarter();
                    start.roll(Calendar.DATE, -1);
                    int maxDate = start.get(Calendar.DATE);
                    start.roll(Calendar.DATE, 1);
                    for (int i = 1; i <= maxDate; i++) {
                        String str = sdf.format(start.getTime());
                        jsonObject.put(str, hashMap.getOrDefault(str, 0));
                        start.add(Calendar.DAY_OF_MONTH, 1);
                    }
                    JSONObject object = new JSONObject();
                    object.put(name, jsonObject);
                    jsonArray.add(object);
                }
            }
            DataBaseConnection.closeConnection(connection);
            result = jsonArray.toString();
        }
        return result;
    }

    private Calendar getYearStarter() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Integer.parseInt(year), Calendar.JANUARY, 1);
        return calendar;
    }

    private Calendar getMonthStarter() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, Integer.parseInt(year));
        calendar.set(Calendar.MONTH, Integer.parseInt(month) - 1);
        calendar.set(Calendar.DATE, 1);
        return calendar;
    }
}